#include "loadingFunctions.h"

using namespace std;

//Returns whether the system is little-endian
bool littleEndian()
{
	//The short value 1 has bytes (1, 0) in little-endian and (0, 1) in big-endian
	short s = 1;
	return (((char*)&s)[0]) == 1;
}

//Converts a two-character array to an unsigned short, using little-endian form
unsigned short toUShort(const char* bytes)
{
	return (unsigned short)(((unsigned char)bytes[1] << 8) | (unsigned char)bytes[0]);
}

//Converts a four-character array to a float, using little-endian form
float toFloat(const char* bytes)
{
	float f;
	if (littleEndian())
	{
		((char*)&f)[0] = bytes[0];
		((char*)&f)[1] = bytes[1];
		((char*)&f)[2] = bytes[2];
		((char*)&f)[3] = bytes[3];
	}
	else
	{
		((char*)&f)[0] = bytes[3];
		((char*)&f)[1] = bytes[2];
		((char*)&f)[2] = bytes[1];
		((char*)&f)[3] = bytes[0];
	}
	return f;
}

//Reads the next two bytes as an unsigned short, using little-endian form
unsigned short readUShort(ifstream &input)
{
	char buffer[2];
	input.read(buffer, 2);
	return toUShort(buffer);
}

//Reads the next four bytes as a float, using little-endian form
float readFloat(ifstream &input)
{
	char buffer[4];
	input.read(buffer, 4);
	return toFloat(buffer);
}

//Calls readFloat three times and returns the results as a Vector object
Vector readVec3f(ifstream &input)
{
	float x = readFloat(input);
	float y = readFloat(input);
	float z = readFloat(input);
	return Vector(x, y, z);
}

//Converts a four-character array to an integer, using little-endian form
int toInt(const char* bytes)
{
	return (int)(((unsigned char)bytes[3] << 24) |
		((unsigned char)bytes[2] << 16) |
		((unsigned char)bytes[1] << 8) |
		(unsigned char)bytes[0]);
}

//Converts a two-character array to a short, using little-endian form
short toShort(const char* bytes)
{
	return (short)(((unsigned char)bytes[1] << 8) |
		(unsigned char)bytes[0]);
}

//Reads the next four bytes as an integer, using little-endian form
int readInt(ifstream &input)
{
	char buffer[4];
	input.read(buffer, 4);
	return toInt(buffer);
}

//Reads the next two bytes as a short, using little-endian form
short readShort(ifstream &input)
{
	char buffer[2];
	input.read(buffer, 2);
	return toShort(buffer);
}

//Reads one byte as a short, using little-endian form
short readShortOneByte(ifstream &input)
{
	char buffer[2];
	input.read(buffer, 1);
	buffer[1] = 0;
	return toShort(buffer);
}